package com.fruit.service.lightpay.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.fruit.constants.LightPayConstant;
import com.fruit.constants.PayConstant;
import com.fruit.mapper.lightpay.LightPayMapper;
import com.fruit.pojo.lightpay.LightPayCashier;
import com.fruit.pojo.lightpay.LightPayCashierAlipay;
import com.fruit.pojo.lightpay.LightPayCashierWechat;
import com.fruit.pojo.sys.AlipayConfig;
import com.fruit.pojo.sys.WechatConfig;
import com.fruit.service.lightpay.LightPayNotifyManager;
import com.fruit.service.pay.PayManager;
import com.fruit.util.CustomUtil;
import com.fruit.util.DataUtil;
import com.fruit.util.DateUtil;
import com.fruit.util.ResultInfo;
import com.fruit.util.ResultUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 收银台回调
 *
 * @author shibeilei
 * @version 2017.12.06 11:00
 *
 */
@Slf4j
@Service
public class LightPayNotifyService implements LightPayNotifyManager {

	@Autowired
	private LightPayMapper lightPayMapper;

	@Autowired
	private PayManager payService;

	@Autowired
	private LightPayLogService lightPayService;
	
	@Value("${alipay.money}")
	private String alipayMoney;

	@Value("${wechat.money}")
	private String xwMoney;

	@Override
	public Map<String, Object> updateLightPayCashier(String tradeId, LightPayCashierAlipay result, AlipayConfig ac) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		LightPayCashier lpc = null;
		try {
			String tradeStatus = result.getTradeStatus();
			String code = result.getOutTradeNo();
			log.info("[{}]-【支付宝回调】-【收银流水号：{}】-【开始】", tradeId, code);
			// 查询收银记录
			lpc = lightPayMapper.getLightpayCashierByCode(code);
			if (lpc == null) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "null", "支付宝-收银记录不存在!"));
				return resMap;
			}

			if (lpc != null && PayConstant.State.notpay.equals(lpc.getState())) {
				LightPayCashierAlipay lpca = new LightPayCashierAlipay();
				BigDecimal totalAmount = DataUtil.getBigDecimal(result.getTotalAmount());
				
				if (PayConstant.PayValue.test.equals(ac.getPayValue())) {
					lpca.setTotalAmount(alipayMoney);
				} else {
					lpca.setTotalAmount(lpc.getPrice().toString());
				}
				
				if (DataUtil.getBigDecimal(lpca.getTotalAmount()).compareTo(totalAmount) == 0) {
					log.info("[{}]-【支付宝回调】-【保存收银记录】", tradeId, code);
					String curTime = DateUtil.getTime();
					lpca.setAppId(result.getAppId());
					lpca.setCashierId(lpc.getId());
					lpca.setTradeNo(result.getTradeNo());
					lpca.setTotalAmount(result.getTotalAmount());
					lpca.setSellerId(result.getSellerId());
					lpca.setBuyerId(result.getBuyerId());
					lpca.setTradeStatus(tradeStatus);
					lpca.setRefundFee(result.getRefundFee());
					lpca.setGmtCreate(result.getGmtCreate());
					lpca.setGmtPayment(result.getGmtPayment());
					lpca.setGmtRefund(result.getGmtRefund());
					lpca.setGmtClose(result.getGmtClose());
					lpca.setTimeStart(result.getGmtCreate());
					lpca.setTimeEnd(curTime);
					lpca.setState(PayConstant.RHandelState.yes.getValue());
					lpc.setBackState(PayConstant.BackState.backok.getValue());
					if (StringUtils.equals(tradeStatus, LightPayCashierAlipay.TRADE_SUCCESS)
							|| StringUtils.equals(tradeStatus, LightPayCashierAlipay.TRADE_FINISHED)) {
						lpc.setPayMode(PayConstant.PayMode.alipay.getValue());
						lpc.setState(PayConstant.State.pay.getValue());
					} else {
						lpc.setState(PayConstant.State.faile.getValue());
					}
					lpc.setFinishTime(curTime);
					int num = lightPayMapper.updateLightpayStateById(lpc);
					if (num == 1) {
						num = lightPayMapper.saveLightpayCashierAlipayNotify(lpca);
					}
					if (num == 0) {
						resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "error", "更新失败!"));
						return resMap;
					}
					if (num == 1 && PayConstant.State.pay.equals(lpc.getState())) {
						// 处理订单
						updateTransaction(tradeId, lpc);
					}
					resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "OK", "更新成功!"));
					return resMap;
				}
			}
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "error", "更新失败!"));
			return resMap;
		} finally {
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				log.error("[{}]-【支付宝回调】-【异常】-【{}：{}】", tradeId, ri.getCode(), ri.getMessage());
				if (lpc != null) {
					// 插入错误日志
					lightPayService.newSaveExceptionLightPay(tradeId, "LightPayNotifyService",
							LightPayConstant.ServiceState.update.getValue(), lpc.getCode(), lpc.getUserId(),
							ri.getCode(), ri.getMessage());
				}
			} else {
				log.info("[{}]-【支付宝回调】-【成功】", tradeId);
			}
			log.info("[{}]-【支付宝回调】-【结束】", tradeId);
		}
	}
	
	/**
	 * 
	 * @param tradeId 全局唯一ID
	 * @param lpc 收银记录
	 */
	public void updateTransaction(String tradeId, LightPayCashier lpc) {
		try {
			log.info("[{}]-【处理订单】-【开始】", tradeId);
			String transactionCode = lpc.getTransactionCode();
			String payMode = lpc.getPayMode();
			long lpcId = lpc.getId();
			// 异步处理业务逻辑
			Map<String, Object> resMap = payService.updateTransaction(tradeId, transactionCode, payMode);
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				// 插入日志
				log.error("[{}]-【处理订单】-【异常】-【{}：{}】", tradeId, "handelOrder", "处理订单失败");
				lightPayService.newSaveExceptionLightPay(tradeId, "LightPayNotifyService",
						LightPayConstant.ServiceState.handelOrder.getValue(), lpc.getCode(), lpc.getUserId(),
						"handelOrder", "处理订单失败");
			} else {
				log.info("[{}]-【处理订单】-【成功】", tradeId);
				log.info("[{}]-【更新收银处理结果】-【开始】", tradeId);
				lpc = lightPayMapper.getLightpayCashierById(lpcId);
				lpc.setResultHandelState(PayConstant.RHandelState.yes.getValue());
				int num = lightPayMapper.updateLightpayRhState(lpc);
				if (num == 0) {
					// 插入日志
					log.error("[{}]-【更新收银处理结果】-【异常】-【{}：{}】", tradeId, "updateHandel", "更新收银处理结果失败");
					lightPayService.newSaveExceptionLightPay(tradeId, "LightPayNotifyService",
							LightPayConstant.ServiceState.updateHandel.getValue(), lpc.getCode(), lpc.getUserId(),
							"updateHandel", "更新收银处理结果失败");
				} else {
					log.info("[{}]-【更新收银处理结果】-【成功】", tradeId);
				}
			}
		} catch (Exception e) {
			log.error("[{}]-【处理订单】-【异常】-【{}：{}】", tradeId, "updateTransaction", "处理订单失败");
			lightPayService.newSaveExceptionLightPay(tradeId, "LightPayNotifyService",
					LightPayConstant.ServiceState.handelOrder.getValue(), lpc.getCode(), lpc.getUserId(),
					"updateTransaction", "处理订单失败");
		}
		log.info("[{}]-【处理订单】-【结束】", tradeId);
	}

	/**
	 * DUBBO 异步暂时不成熟
	 */
	@Override
	public void onreturn(Map<String, Object> resMap, String transactionCode, String payMode, long lpcId) {
		try {
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				// 插入日志
				log.info("【插入日志】");
			} else {
				LightPayCashier lpc = lightPayMapper.getLightpayCashierById(lpcId);
				lpc.setResultHandelState(PayConstant.RHandelState.yes.getValue());
				int num = lightPayMapper.updateLightpayRhState(lpc);
				if (num == 0) {
					// 插入日志
					log.info("【插入日志】");
				}
			}
		} catch (Exception e) {
		}
	}

	@Override
	public Map<String, Object> updateLightPayCashierByWechat(String tradeId, Map<String, String> params, String xml, WechatConfig wc) {
		Map<String, Object> resMap = new HashMap<String, Object>();
		LightPayCashier lpc = null;
		try {
			String resultCode = params.get("result_code");
			String code = params.get("out_trade_no");
			log.info("[{}]-【微信支付回调】-【收银流水号：{}】-【开始】", tradeId, code);

			// 查询收银记录
			lpc = lightPayMapper.getLightpayCashierByCode(code);
			if (lpc == null) {
				resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "null", "微信支付-收银记录不存在!"));
				return resMap;
			}

			if (lpc != null && PayConstant.State.notpay.equals(lpc.getState())) {
				LightPayCashierWechat lpcw = new LightPayCashierWechat();
				String totalFee = params.get("total_fee");
				
				if (PayConstant.PayValue.test.equals(wc.getPayValue())) {
					lpcw.setTotalFee(xwMoney);
				} else {
					lpcw.setTotalFee(CustomUtil.getMoney(lpc.getPrice()));
				}
				if (StringUtils.equals(lpcw.getTotalFee(), totalFee)) {
					String curTime = DateUtil.getTime();
					lpcw.setAppId(params.get("appid"));
					lpcw.setCashierId(lpc.getId());
					lpcw.setBankType(params.get("bank_type"));
					lpcw.setTradeType(params.get("trade_type"));
					lpcw.setTotalFee(totalFee);
					lpcw.setTransactionId(params.get("transaction_id"));
					lpcw.setTimeStart(DateUtil.fomatDateTime(lpc.getCreateTime(), "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss"));
					lpcw.setTimeEnd(params.get("time_end"));
					lpcw.setResultCode(resultCode);
					lpcw.setResp2Content(xml);
					lpcw.setState(PayConstant.RHandelState.yes.getValue());
					lpc.setBackState(PayConstant.BackState.backok.getValue());
					if (StringUtils.equals(resultCode, PayConstant.CODE_SUCCESS)) {
						lpc.setPayMode(PayConstant.PayMode.wechat.getValue());
						lpc.setState(PayConstant.State.pay.getValue());
					} else {
						lpc.setState(PayConstant.State.faile.getValue());
					}
					lpc.setFinishTime(curTime);
					int num = lightPayMapper.updateLightpayStateById(lpc);
					if (num == 1) {
						num = lightPayMapper.saveLightpayCashierWechatNotify(lpcw);
					}
					if (num == 0) {
						resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "error", "更新失败"));
						return resMap;
					}

					if (num == 1 && PayConstant.State.pay.equals(lpc.getState())) {
						updateTransaction(tradeId, lpc);
					}
					resMap.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "OK", "支付成功"));
					return resMap;
				}

			}
			resMap.put("result", ResultUtil.initResult(ResultInfo.ERROR, "error", "更新失败"));
			return resMap;
		} finally {
			ResultInfo ri = (ResultInfo) resMap.get("result");
			if (ResultInfo.ERROR.equals(ri.getState())) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				log.error("[{}]-【微信支付回调】-【异常】-【{}：{}】", tradeId, ri.getCode(), ri.getMessage());
				if (lpc != null) {
					// 插入错误日志
					lightPayService.newSaveExceptionLightPay(tradeId, "LightPayNotifyService",
							LightPayConstant.ServiceState.update.getValue(), lpc.getCode(), lpc.getUserId(),
							ri.getCode(), ri.getMessage());
				}
			} else {
				log.info("[{}]-【微信支付回调】-【成功】", tradeId);
			}
			log.info("[{}]-【微信支付回调】-【结束】", tradeId);
		}
	}

}
